package pers.lolicer.redtidelibrary.utils

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log
import androidx.appcompat.content.res.AppCompatResources
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.toArgb
import org.w3c.dom.Element
import pers.lolicer.redtidelibrary.R
import pers.lolicer.redtidelibrary.config.BitmapImageConfig
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import javax.xml.parsers.DocumentBuilderFactory

class EpubUtils {
    @SuppressLint("Recycle")
    fun getCover(context: Context, contentUri: Uri): ImageBitmap {
        // BitmapImageConfig.init(context)

        try {
            val file = FileUtils().saveFileToCache(context, contentUri)
            val epub = ZipFile(file)

            val container = epub.getEntry("META-INF/container.xml")
            val containerEle = container.getDocumentElement(epub)
            val fullPath = containerEle.getFullPath()

            val contentOpf = epub.getEntry(fullPath)
            val contentOpfEle = contentOpf.getDocumentElement(epub)
            val coverContent = contentOpfEle.getCoverContent()
            if(coverContent != ""){
                var path = ""
                if("/" in fullPath){ path = fullPath.substringBeforeLast("/") + "/" }

                val cover = epub.getEntry(path + contentOpfEle.getCoverHref(coverContent))

                val bitmap = BitmapFactory.decodeStream(epub.getInputStream(cover))
                Log.d("epub0", "getCover: ")

                // 对于透明背景的PDF，要渲染背景颜色
                val backgroundBitmap = Bitmap.createBitmap(
                    bitmap.width,
                    bitmap.height,
                    Bitmap.Config.ARGB_8888
                )
                val canvas = android.graphics.Canvas(backgroundBitmap)
                canvas.drawColor(AppColor.CoverBackground(context).toArgb())
                canvas.drawBitmap(bitmap, 0f, 0f, null)

                return backgroundBitmap.trimToA4Size().asImageBitmap()
            }
            Log.d("epub1", "")
            return BitmapImageConfig.createBitmap(context, R.drawable.type_epub)
        }
        catch (e: NullPointerException){
            e.printStackTrace()
            Log.d("epub2", "")
            return  BitmapImageConfig.createBitmap(context, R.drawable.type_epub)
        }
        catch (e: SecurityException){
            e.printStackTrace()
            Log.d("epub3", "")
            return  BitmapImageConfig.createBitmap(context, R.drawable.type_err)
        }
    }
}


private fun ZipEntry.getDocumentElement(zipFile: ZipFile): Element {
    val containerContent = zipFile.getInputStream(this).reader().readText()
    val factory = DocumentBuilderFactory.newInstance()
    val builder = factory.newDocumentBuilder()
    val document = builder.parse(containerContent.byteInputStream())
    return document.documentElement
}

private fun Element.getFullPath(): String {
    val rootFiles = this.getElementsByTagName("rootfiles")
    if(rootFiles.length == 1){
        val rootfileList = rootFiles.item(0).childNodes
        for (i in 0 until rootfileList.length) {
            val node = rootfileList.item(i)
            if (node.nodeType == org.w3c.dom.Node.ELEMENT_NODE && node.nodeName == "rootfile") {
                // 获取rootfile的属性
                return node.attributes.getNamedItem("full-path").nodeValue
            }
        }
    }
    return ""
}

private fun Element.getCoverContent(): String{
    val metas = this.getElementsByTagName("meta")
    if(metas.length > 0){
        for(i in 0 until  metas.length){
            val node = metas.item(i)
            if(node.nodeType == org.w3c.dom.Node.ELEMENT_NODE && node.nodeName == "meta"){
                if(node.attributes.getNamedItem("name").nodeValue == "cover"){
                    return node.attributes.getNamedItem("content").nodeValue
                }
            }
        }
    }
    return ""
}

private fun Element.getCoverHref(coverContent: String): String{
    val manifest = this.getElementsByTagName("manifest")
    if(manifest.length > 0){
        val itemList = manifest.item(0).childNodes
        for(i in 0 until itemList.length){
            val node = itemList.item(i)
            if(node.nodeType == org.w3c.dom.Node.ELEMENT_NODE && node.nodeName == "item"){
                if(node.attributes.getNamedItem("id").nodeValue == coverContent){
                    return node.attributes.getNamedItem("href").nodeValue
                }
            }
        }
    }
    return ""
}